<template>
    <div>
        <div class="layui-row">
            <div class="layui-col-xs5">
                <div class="main-left">
                    <div class="fl extract" style="margin: 19px 15px 15px; color: #FFFFFF;">
                        抽取奖项
                        <select style="height: 24px; border-radius: 2px; border: 1px #FFFFFF solid;"
                                v-model="item"
                        >
                            <option v-for="(item, index) of lotto.settings" :value="item.name" :key="index">{{ item.name }}</option>
                        </select>
                    </div>
                    <div class="count fr">参加人数<span>{{ activePlayers.length }}</span>人</div>
                    <div class="clear"></div>
                    <div class="extract-user">
                        <div class="header-img" style="height: 171.5px;">
                            <img v-if="currentPlayer" :src="currentPlayer.avatar"/>
                            <img v-else src="/images/logo.png"/>
                        </div>
                        <div class="layui-elip">
                            <span class="name">{{ currentPlayer ? currentPlayer.nickname : ''}}</span>
                        </div>
                    </div>
                    <div class="start">
                        <button class="layui-btn layui-btn-primary" @click="startHandler">{{ startBtnText }}</button>
                    </div>
                    <div class="main-left-bottom">
                        <div class="fl extract">
                            一次抽取
                            <input style="border-radius: 2px; width: 50px; height: 24px; display: inline-block;"
                                   type="text" class="layui-input"
                                   v-model="number"
                            >
                            人
                        </div>
                        <button class="fr layui-btn layui-btn-primary" @click="replay">重玩</button>
                    </div>
                </div>
            </div>
            <div class="layui-col-xs7">
                <div class="main-right">
                    <div class="title">获奖名单</div>
                    <div class="winning-list">
                        <ul v-if="winnersList === 'current'" class="layui-col-space30 list">
                            <li v-for="w of lastWinners" :key="w.id" class="item">
                                <img :src="w.avatar">
                                <div class="layui-elip name">{{ w.nickname }}</div>
                            </li>
                        </ul>
                        <div v-else-if="winnersList === 'all'" class="all-winning-list">
                            <div class="list-box"
                                 v-for="(item, index) of lotto.settings"
                                 :key="index"
                                 v-if="groupedWinners[item.name]"
                            >
                                <span class="kl-title3" style="display:block;">{{ item.name }}</span>
                                <ul class="layui-col-space30 list">
                                    <li class="item" v-for="p of groupedWinners[item.name]" :key="p.id">
                                        <img :src="p.avatar">
                                        <div class="layui-elip name">{{ p.nickname }}</div>
                                    </li>
                                </ul>
                            </div>
                        </div>
                        <div class="clear"></div>
                    </div>
                    <div class="main-right-bottom">
                        <button class="layui-btn layui-btn-primary z"
                                @click="handleResetCurrent"
                        >重置当前抽奖</button>
                        <button class="layui-btn layui-btn-primary z"
                                @click="handleWinnerList('current')"
                        >{{ showOrHide('current') }}当前中奖名单</button>
                        <button class="layui-btn layui-btn-primary alllist"
                                @click="handleWinnerList('all')"
                        >{{ showOrHide('all') }}所有中奖名单</button>
                    </div>
                </div>
            </div>
        </div>
        <div v-show="awardGiving" class="kl-frame">
            <transition name="award-giving"
                        @after-enter="handleWinnerShown"
                        @after-leave="handleAwardGivingDone"
            >
                <div v-show="awardGiving & winnerShow" class="winning-content">
                    <div v-if="currentPlayer" class="extract-user">
                        <img src="/images/crown.png" class="crown"/>
                        <div class="header-img">
                            <img :src="currentPlayer.avatar"/>
                        </div>
                        <div class="layui-elip winname">{{ currentPlayer.nickname }}</div>
                    </div>
                    <img src="/images/d_bg01.png" class="d_bg01">
                    <img src="/images/d_bg02.png" class="layui-anim layui-anim-rotate layui-anim-loop d_bg02">
                </div>
            </transition>
            <div class="frame-bg"></div>
        </div>
    </div>
</template>

<script>
    export default {
        name: "Play",
        data() {
            return {
                item: this.getFirstItem(),
                number: 0,

                currentPlayer: null,
                players: [],

                status: 'ready',
                statuses: {
                    ready: {
                        btnText: '开始抽奖',
                        handler: this.start,
                        nextStatus: 'rolling',
                    },
                    rolling: {
                        btnText: '停止',
                        handler: this.picking,
                        nextStatus: 'picking',
                    },
                    picking: {
                        btnText: '抽奖中...',
                        handler: this.pause,
                        nextStatus: 'paused',
                    },
                    paused: {
                        btnText: '继续',
                        handler: this.resume,
                        nextStatus: 'picking',
                    },
                },
                awardGiving: false,
                winnerShow: false,

                rollingInterval: 50,
                nextPickTime: 0,
                nextPickTimeRange: [2, 3],

                winnersList: 'current',

                lastWinners: [],

                lastWinnersStorageKey: '',
            };
        },
        props: {
            lotto: {
                type: Object,
                required: true,
            },
            playersData: {
                type: Array,
                required: true,
            },
        },
        mounted() {
            this.copyPlayers();
            this.initCurrentPlayer();
            this.lastWinnersStorageKey = `lastWinners.${this.lotto.id}`;
            this.initLastWinners();

            Echo.channel(`lotto.${this.lotto.id}`)
                .listen('.player-joined', ({player}) => {
                    if (_.findIndex(this.players, p => p.id == player.id) === -1) {
                        this.players.unshift(player);
                    }
                });
        },
        computed: {
            startBtnText() {
                return this.statuses[this.status].btnText;
            },
            startHandler() {
                return this.statuses[this.status].handler;
            },
            activePlayers() {
                return _.filter(this.players, (p) => {
                    return !p.award;
                });
            },
            winners() {
                return _.filter(this.players, p => p.award);
            },
            groupedWinners() {
                return _.groupBy(this.winners, p => p.award);
            },
        },
        methods: {
            initCurrentPlayer() {
                this.currentPlayer = _.last(this.activePlayers);
            },
            copyPlayers() {
                this.players = this.playersData.map((p) => {
                    return {
                        id: p.id,
                        avatar: p.avatar,
                        nickname: p.nickname,
                        award: p.pivot.award,
                    };
                });
            },
            initLastWinners() {
                let data = localStorage.getItem(this.lastWinnersStorageKey);
                data = data ? data : '';
                try {
                    data = JSON.parse(data);
                } catch (e) {
                    data = [];
                }

                data.forEach((d) => {
                    this.lastWinners.push(_.find(this.players, (p) => p.id === d));
                });
            },
            getFirstItem() {
                let firstLotto = this.lotto.settings[0];

                return firstLotto ? firstLotto.name : '';
            },
            start() {
                if (this.number == 0) {
                    layer.msg('1个人都没有，抽谁呢？');
                    return;
                }

                this.status = this.statuses[this.status].nextStatus;
                this.clearLastWinners();
                this.roll();
            },
            picking() {
                this.status = this.statuses[this.status].nextStatus;
                this.setNextPickTime();
            },
            pause() {
                this.status = this.statuses[this.status].nextStatus;
            },
            resume() {
                this.status = this.statuses[this.status].nextStatus;
                this.roll();
            },
            stop() {
                this.status = 'ready';
                this.currentPlayer = _.last(this.activePlayers);
            },
            roll() {
                let ap = this.activePlayers;

                // 如果可中奖人数,或者本次抽奖人数为0,则停止抽奖
                if (ap.length === 0 || this.number === 0) {
                    this.stop();
                    return;
                }

                // 如果正在颁奖,则暂停
                if (this.awardGiving || this.status === 'paused') {
                    return;
                }

                this.currentPlayer = ap[Math.floor(Math.random() * ap.length)];

                if (this.status === 'picking') {
                    this.nextPickTime -= this.rollingInterval;

                    if (this.nextPickTime <= 0) {
                        this.handleGiveAward();
                        return;
                    }
                }
                setTimeout(this.roll, this.rollingInterval);
            },
            handleGiveAward() {
                this.$set(this.currentPlayer, 'award', this.item);
                this.lastWinners.unshift(this.currentPlayer);
                localStorage.setItem(this.lastWinnersStorageKey, JSON.stringify(this.lastWinners.map(w => w.id)));
                this.number--;
                this.awardGiving = true;
                this.winnerShow = true;

                this.ajaxGiveAward();
            },
            ajaxGiveAward() {
                $.ajax({
                    url: `/lottos/${this.lotto.id}/award`,
                    method: 'post',
                    data: {
                        userId: this.currentPlayer.id,
                        item: this.item,
                    },
                });
            },
            handleWinnerShown() {
                this.winnerShow = false;
            },
            handleAwardGivingDone() {
                this.awardGiving = false;
                this.setNextPickTime();
                this.roll();
            },
            setNextPickTime() {
                this.nextPickTime = _.random(...this.nextPickTimeRange) * 1000;
            },
            replay() {
                layer.confirm('要重新来过吗？', {
                    icon: 3,
                    title: '重玩'
                }, (index) => {
                    this.ajaxReplay(() => {
                        this.players.forEach((item) => {
                            item.award = '';
                        });
                        this.initCurrentPlayer();
                        this.clearLastWinners();
                    });

                    layer.close(index);
                });
            },
            ajaxReplay(cb) {
                $.ajax({
                    url: `/lottos/${this.lotto.id}/replay`,
                    method: 'post',
                })
                 .done(() => {
                     cb();
                 });
            },

            handleWinnerList(type) {
                if (this.winnersList === type) {
                    this.winnersList = 'none';
                } else {
                    this.winnersList = type
                }
            },
            showOrHide(type) {
                if (this.winnersList === type) {
                    return '隐藏';
                } else {
                    return '显示';
                }
            },
            handleResetCurrent() {
                if (this.lastWinners.length === 0) {
                    layer.msg('当前没有抽奖');
                    return;
                }

                layer.confirm('重置最近一次抽取的玩家奖项？', {
                    icon: 3,
                    title: '重置当前'
                }, (index) => {
                    this.ajaxResetCurrent(() => {
                        this.lastWinners.forEach((item) => {
                            item.award = '';
                        });
                        this.clearLastWinners();
                        this.initCurrentPlayer();
                    });

                    layer.close(index);
                });
            },
            ajaxResetCurrent(cb) {
                $.ajax({
                    url: `/lottos/${this.lotto.id}/reset-current`,
                    method: 'post',
                    data: {
                        user_ids: this.lastWinners.map(w => w.id),
                    },
                })
                 .done(() => {
                     cb();
                 });
            },

            clearLastWinners() {
                this.lastWinners = [];
                localStorage.removeItem(this.lastWinnersStorageKey);
            }
        },
        watch: {
            item: {
                handler(newValue) {
                    let index = _.findIndex(this.lotto.settings, (item) => {
                        return item.name == newValue;
                    });

                    if (index !== -1) {
                        let item = this.lotto.settings[index];
                        this.number = item.number ? item.number : 0;
                    }
                },
                immediate: true,
            },
            number(newValue, oldValue) {
                newValue = newValue.toString();

                let trimmed = newValue.trim();
                if (trimmed.length !== newValue.length) {
                    this.number = trimmed;
                    return;
                }
                if (newValue === '') {
                    return;
                }

                let n = parseInt(newValue);
                if (isNaN(n)) {
                    this.number = '';
                    return;
                }

                if (n !== Number(newValue)) {
                    this.number = n;
                }
            },
            players() {
                if (!this.currentPlayer) {
                    this.initCurrentPlayer();
                }
            },
        },
    }
</script>

<style>
    .award-giving-enter-active {
        -webkit-animation: zoomIn .5s linear 0s 1 both;
        animation: zoomIn .5s linear 0s 1 both;
    }

    .award-giving-leave-active {
        -webkit-animation: zoomOut 1s linear 1s 1 both;
        animation: zoomOut 1s linear 1s 1 both;
    }
</style>